SICP 习题 1.9
Exercise 1.9. Each of the following two procedures defines a method for adding two positive integers in terms of the procedures inc, which increments its argument by 1, and dec, which decrements its argument by 1.
练习题 1.9. 以下两个过程都定义了一个方法,用于在 inc 和 dec 这两个过程的基础上,将两个正整数相加,其中 inc 将其参数加1,dec 将其参数减 1。
Using the substitution model, illustrate the process generated by each procedure in evaluating (+ 4 5). Are these processes iterative or recursive?
使用替换模型,说明评估(+ 4 5)时每个过程生成的过程。这些过程是迭代的还是递归的?
#lang racket
(define (inc x)
(+ x 1))
(define (dec x)
(- x 1))
(define (p a b)
(if (= a 0)
b
(inc (p (dec a) b))))
(define (++ a b)
(if (= a 0)
b
(++ (dec a) (inc b))))
(displayln (p 2 3))
(displayln (++ 2 3))
分析
让我们逐步分析这两个过程 (+) 和 (++) 是如何计算 (+ 4 5) 的,并判断它们生成的过程是递归的还是迭代的。
过程 1: (+ a b) 使用 p 代替 +
定义如下:
(define (+ a b)
(if (= a 0)
b
(inc (+ (dec a) b))))
评估 (+ 4 5)
- 计算
(+ 4 5),由于a不等于0,我们进入else部分,计算(inc (+ (dec 4) 5)) - 计算
(dec 4)得到3,所以我们要计算(inc (+ 3 5)) - 计算
(+ 3 5),由于a不等于0,我们进入else部分,计算(inc (+ (dec 3) 5)) - 计算
(dec 3)得到2,所以我们要计算(inc (+ 2 5)) - 计算
(+ 2 5),由于a不等于0,我们进入else部分,计算(inc (+ (dec 2) 5)) - 计算
(dec 2)得到1,所以我们要计算(inc (+ 1 5)) - 计算
(+ 1 5),由于a不等于0,我们进入else部分,计算(inc (+ (dec 1) 5)) - 计算
(dec 1)得到0,所以我们要计算(inc (+ 0 5)) - 现在计算
(+ 0 5),由于a = 0,返回b = 5 - 返回的结果传递回第 8 步,得到
(inc 5),即6 - 返回的结果传递回第 7 步,得到
(inc 6),即7 - 返回的结果传递回第 6 步,得到
(inc 7),即8 - 返回的结果传递回第 5 步,得到
(inc 8),即9 - 返回的结果传递回第 4 步,得到
(inc 9),即10 - 返回的结果传递回第 3 步,得到
(inc 10),即11 - 返回的结果传递回第 2 步,得到
(inc 11),即12 - 返回的结果传递回第 1 步,得到
(inc 12),即13
结果为 13。这个过程在每一层递归中都有未完成的计算,因此生成了一个递归过程。
过程 2: (++ a b)
定义如下:
(define (++ a b)
(if (= a 0)
b
(++ (dec a) (inc b))))
评估 (++ 4 5)
- 计算
(++ 4 5),由于a不等于0,我们进入else部分,计算(++ (dec 4) (inc 5)) - 计算
(dec 4)得到3,(inc 5)得到6,所以计算(++ 3 6) - 计算
(++ 3 6),由于a不等于0,我们进入else部分,计算(++ (dec 3) (inc 6)) - 计算
(dec 3)得到2,(inc 6)得到7,所以计算(++ 2 7) - 计算
(++ 2 7),由于a不等于0,我们进入else部分,计算(++ (dec 2) (inc 7)) - 计算
(dec 2)得到1,(inc 7)得到8,所以计算(++ 1 8) - 计算
(++ 1 8),由于a不等于0,我们进入else部分,计算(++ (dec 1) (inc 8)) - 计算
(dec 1)得到0,(inc 8)得到9,所以计算(++ 0 9) - 现在
a = 0,返回b = 9
最终结果为 9。在每一步递归中,(++ a b) 的计算完全依赖于调用参数的值而不是层层嵌套的计算,这生成了一个迭代过程,因为递归调用没有生成未完成的计算,消耗的空间和时间是恒定的。
结论
(+)生成的是递归过程,因为每次调用都会增加一个等待完成的inc计算,形成嵌套。(++)生成的是迭代过程,因为每次调用没有嵌套的计算,计算过程可以在恒定的内存空间内完成。
本文作者:Maeiee
本文链接:SICP 习题 1.9
版权声明:如无特别声明,本文即为原创文章,版权归 Maeiee 所有,未经允许不得转载!
喜欢我文章的朋友请随缘打赏,鼓励我创作更多更好的作品!
